﻿using System.Collections.Generic;
using Framework.Core.BootStrapper.Deployment;
using Framework.Core.Io;
using Framework.Core.Process;
using Framework.Core.Process.Tasks;
using Rhino.Mocks;
using Xunit;

namespace Framework.Tests.Core.BootStrapper
{
    public class DeployPluginTest
    {
        private readonly DeployPlugin plugin;
        private readonly MockRepository mockRepository = new MockRepository();
        private readonly IProcessController localProcessController;
        private readonly IProcessController remoteProcessController;
        private readonly DeployPlugin.IRemoteProcessControllerFactory remoteProcessControllerFactory;

        public DeployPluginTest()
        {
            localProcessController = mockRepository.StrictMock<IProcessController>();
            remoteProcessController = mockRepository.StrictMock<IProcessController>();
            remoteProcessControllerFactory = mockRepository.StrictMock<DeployPlugin.IRemoteProcessControllerFactory>();
            plugin = new DeployPlugin(localProcessController, remoteProcessControllerFactory);
        }

        [Fact]
        public void Should_create_remote_process()
        {
            var deployPluginArgs = new DeployPluginArgs
                                   {
                                       Machine = "machine",
                                       Arguments = "/args",
                                       Password = "pwd"
                                   };

            var processController = new DeployPlugin.RemoteProcessControllerFactory().Create(deployPluginArgs);

            Assert.NotNull(processController);
        }

        [Fact]
        public void Should_have_constructors_without_args()
        {
            Assert.NotNull(new DeployPlugin());
        }

        [Fact]
        public void Should_deploy_exe()
        {
            var deployPluginArgs = new DeployPluginArgs
                                   {
                                       Machine = @"remoteMachine",
                                       User = @"domain\user",
                                       Password = "password",
                                       ExecutablePath = @"D:\wcf\svc.exe",
                                       RemotePath = @"d:\sandbox",
                                       Arguments = "/p:WcfHost /i /a:{/p:WcfHost,/Env:Prod}"
                                   };

            remoteProcessControllerFactory
                .Expect(x => x.Create(deployPluginArgs))
                .Return(remoteProcessController);
            
            localProcessController
                .Expect(x => x.Start(new PsZip.PsZipCompress(@"D:\wcf", @"D:\wcf.zip")))
                .Return(GetSuccessProcessResult());

            localProcessController
                .Expect(x => x.Start(new Copy(@"D:\wcf.zip", @"\\remoteMachine\ADMIN$\")))
                .Return(GetSuccessProcessResult());

            var process = new Framework.Core.Process.Process(1, "toto", "titi", "args", false);
            remoteProcessController
                .Expect(x => x.KillLocker(@"d:\sandbox"))
                .Return(new List<IProcess> { process });

            remoteProcessController
                .Expect(x => x.Start(new PsZip.PsZipExtract(@"c:\windows\wcf.zip", @"d:\sandbox")))
                .Return(GetSuccessProcessResult());

            remoteProcessController
                .Expect(x => x.Start(new Command(@"d:\sandbox\svc.exe", "/p:WcfHost /i /a:{/p:WcfHost,/Env:Prod}")))
                .Return(GetSuccessProcessResult());

            remoteProcessController
                .Expect(x => x.Start(process))
                .Return(GetSuccessProcessResult());

            mockRepository.ReplayAll();
            plugin.Execute(deployPluginArgs);
            mockRepository.VerifyAll();
        }

        private static ProcessResult GetSuccessProcessResult()
        {
            return new ProcessResult(0, string.Empty, string.Empty, false);
        }
    }
}
